﻿using System;
using System.Globalization;
using EPiServer.Core;
using EPiServer.DataAbstraction;
using EPiServer.Editor;
using PageTypeBuilder;
using TemplateFoundation.Core;
using TemplateFoundation.Tabs;

namespace TemplateFoundation.PageTypes
{
    /// <summary>
    /// Base class for date folder page types, which in turn are commonly used to list all articles for a specific year or month
    /// </summary>
    public abstract class ArticleDateListingPageBase : ArticleListingPageBase
    {
        /// <summary>
        /// Gets the articles to list if this is a year or month container
        /// </summary>
        public override PageDataCollection Articles
        {
            get
            {
                switch (Type)
                {
                    case ArticleDateListingType.Year:
                        return PageFactory.Instance.GetArticlesByYear(int.Parse(PageName));
                    case ArticleDateListingType.Month:
                        return PageFactory.Instance.GetArticlesByMonth(int.Parse(ParentLink.GetPage().PageName), int.Parse(PageName));
                    default:
                        return new PageDataCollection(0);

                }
            }
        }

        /// <summary>
        /// Gets the type of listing, for example for a year or month container page
        /// </summary>
        public ArticleDateListingType Type
        {
            get
            {
                if (PageName.Length == 4) // Considered a year container if page name is a 4-digit number
                {
                    int year;

                    return int.TryParse(PageName, out year)
                               ? ArticleDateListingType.Year
                               : ArticleDateListingType.None;
                }

                if (PageName.Length<=2) // Considered month container if page name is a 1 or 2-digit number and parent is a year container
                {
                    var parentIsYearContainer = ParentLink.GetPage() is ArticleDateListingPageBase &&
                                                ((ArticleDateListingPageBase) ParentLink.GetPage()).Type ==
                                                ArticleDateListingType.Year;

                    if (parentIsYearContainer)
                    {
                        int month;

                        var isNumber = int.TryParse(PageName, out month);

                        if(isNumber && month > 0 && month <=12)
                        {
                            return ArticleDateListingType.Month;
                        }
                                   
                        return ArticleDateListingType.None;
                    }
                }

                if (PageName.Length<=2) // Considered day container if page name is a 1 or 2-digit number and parent is a month container
                {
                    var parentIsMonthContainer = ParentLink.GetPage() is ArticleDateListingPageBase &&
                                                ((ArticleDateListingPageBase)ParentLink.GetPage()).Type ==
                                                ArticleDateListingType.Month;

                    if (parentIsMonthContainer)
                    {
                        int day;

                        var isNumber = int.TryParse(PageName, out day);

                        if (isNumber && day > 0 && day <=31) // TODO Validate day against parent's month
                        {
                            return ArticleDateListingType.Month;
                        }

                        return ArticleDateListingType.None;
                    }
                }

                return ArticleDateListingType.None;
            }
        }

        /// <summary>
        /// Gets or sets the title of the listing page
        /// </summary>
        /// <remarks>If title is empty, or equal to page name, the title will be the year or month name for the listing</remarks>
        [PageTypeProperty(
            EditCaption = "List title",
            HelpText = "If title is empty, or equal to page name, the title will be the year or month name for the listing",
            UniqueValuePerLanguage = true,
            Tab = typeof(SeoTab),
            Type = typeof(PropertyString))]
        public override string Title
        {
            get
            {
                // Check if the title has been explicitly set
                string title = this.GetPropertyValue(page => page.Title);
                if (!string.IsNullOrEmpty(title) && title != PageName)
                    return title;

                // Check that the title can be parsed to an integer
                int titleAsInteger;
                if (!int.TryParse(title, out titleAsInteger))
                {
                    return title;
                }


                switch(Type)
                {
                    case ArticleDateListingType.Month: // Returns name of the month
                        return new DateTime(
                            DateTime.Now.Year,
                            titleAsInteger,
                            1).ToString("MMMM");
                    default:
                        return PageName;
                }
            }
        }
    }
}